#!/usr/bin/python

"""
    Semantics for draw vs display:
    
    def draw(self, surface, pos, region=None):
        return affected_area_or_None
    
    def display(self, surface, offset=None, region=None):
        return affected_area_or_None
        
    The draw and display methods of objects do basicially the same
    thing: They blit the object's visual aspects to the screen. However,
    the semantics for each function is somewhat different.
    
    The draw method does not care about the object's internal position.
    So if the object, such as an Entity, has some cartesian coordinate
    position somewhere in its parent world, that is disregarded and the
    entity is just drawn at the position on the surface that was passed
    into the method. Also, the "region" argument indicates a portion of
    the object being drawn, not the region of the surface that is being
    drawn to--although the size of the region affected by the object
    when drawing may be equal to the size of the region passed to the
    draw method.
    
    The display method DOES care about the object's internal position.
    The object should display itself based on the vector sum of the
    object's interal position and the offset passed into the method. If
    None is passed as the offset, the object just draws itself at its
    internal position. The "region" argument for the display method
    indicates the region of the surface that is being drawn to, NOT the
    region of the object to drawn. An object should not draw on any part
    of the surface that is outside of the region indicated. A good rule of
    thumb is to return from the display method early if no visible portion
    of the object overlaps with any part of the given region. This will
    save processing time.
"""

import sbak

def main():
    
    # Initialize the engine and create a new Game for the game.
    # These two lines will be pretty much the same for every project done in
    # ScrollBack.
    sbak.init()
    game = sbak.app.Game()
    
    # Register our custom entity types with the entity type library.
    # (game.entitylib is a shortcut to
    # game.resources.loaders['world'].entitylib)
    game.entitylib.add_types(
        Player,
        Orb
    )
    
    # Load the first world into the universe.
    world = game.resources.get(":$bblevel1.wld")
    
    # Create a player instance and put it into the world.
    player = Player(world, (100,100))
    
    # Delete the local reference to the world so it can be unloaded properly
    # later in the game. (This does not unload the world now; it just makes it
    # possible to unload the world later.)
    del world
    
    # Start the game.
    game.start()
    
    
    images = {
        'player' : {
            'dormant' : {
                'right' : [pygame.image.load("bitbot_stand_%0.3i" % i)
                            for i in xrange(3)],
            },
                
            'running' : {
                'right' : [pygame.image.load("") for i in xrange(3)],
            }
        },
        
        'orb' : {
            'dormant' : {
                'right' : [pygame.image.load("orb.png")]
            }
        }
    }
    
    for entity in images.values():
        for action in entity.values():
            action['left'] = [
                pygame.transform.flip(img, True, False) for img in
                    action['right']
            ]
    

class Player(sbak.entity.Actor):
    
    tag = "player"
    
    def __init__(self, pos):
        sbak.entity.Actor.__init__(self, pos = pos, bbox = (0,0,32,32))
        
        # Load an "image sheet" using the resource manager of the game that
        # the actor is a part of. (The game can be accessed as the root of
        # the actor's "main tree")
        # This will load and/or create all images related to the player at once
        # and keep them loaded until the image sheet (and anything else that
        # may be referring to the image sheet's images) are gone.
        self.imagesheet = self.get_root().resources.get(":$bitbot.imgs")
        
        # These are used to determine what the actor is doing and in what
        # direction it is being done.
        self.action = "dormant"
        self.direction = "right"
        
        # This gets the "standing while facing right" image that was loaded
        # earlier as part of the image sheet.
        self.image = self.imagesheet.get(self.action + " " + self.direction)
    
    @sbak.event.handler(sbak.app.UpdateEvent)
    def handle_update(self, hook, e):
        super(Player,self).handle_update(e)
        
        # If the image is an animation then this will keep the animation
        # playing. If it is not an animation then nothing will happen.
        self.image.update()

class Orb(sbak.entity.Actor):
    
    tag = "orb"
    
    def __init__(self, pos):
        sbak.entity.Actor.__init__(self, pos, (32,32))
        self.image = self.get_root().resources.get(":$orb.png")

if __name__ == '__main__':
    main()
    
world = World((32,32))
player = Player((32,32))
orb = Orb((32,32))